﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.Web.UI;

namespace SharingCenter.Web.Classes.SiteEvents
{
    public class SiteEventOperations
    {
        static Page page;

        public static void AddEvent(string appName, string eventName, string xsltFolderInMod, Guid raiserUserId, XElement context, bool isPublic, Guid? groupId)
        {
            if (context.Name != "Event")
            {
                throw new Exception("Root tag name must be \"Event\".");
            }

            Sc_SiteEvent evt;

           
            if (!Convert.ToBoolean(scDataContext.Instance.IsEventDuplicateInSameDay((Guid)raiserUserId, appName, eventName, groupId)))
            {
                // If not exists
                CreateEvent(out evt, ref context, appName, eventName, xsltFolderInMod, raiserUserId, isPublic, groupId);
            }
            else
            {
                // If same event on same app of same user exists in the same day
                CombineEventsInSameDay(out evt, ref context, appName, eventName, raiserUserId, groupId);
            }

            scDataContext.Instance.SubmitChanges();
        }

        public static void AddEvent(string appName, string eventName, string xsltFolderInMod, Guid raiserUserId, XElement context, bool isPublic, Guid? groupId, bool submitChanges)
        {
            if (context.Name != "Event")
            {
                throw new Exception("Root tag name must be \"Event\".");
            }

            Sc_SiteEvent evt;

            if (!Convert.ToBoolean(scDataContext.Instance.IsEventDuplicateInSameDay((Guid)raiserUserId, appName, eventName, groupId)))
            {
                // If not exists
                CreateEvent(out evt, ref context, appName, eventName, xsltFolderInMod, raiserUserId, isPublic, groupId);
            }
            else
            {
                // If same event on same app of same user exists in the same day
                CombineEventsInSameDay(out evt, ref context, appName, eventName, raiserUserId, groupId);
            }

            if (submitChanges)
            {
                scDataContext.Instance.SubmitChanges();
            }
        }

        private static void CreateEvent(out Sc_SiteEvent evt, ref XElement context, string appName, string eventName, string xsltFolderInMod, Guid raiserUserId, bool isPublic, Guid? groupId)
        {
            evt = new Sc_SiteEvent();
            evt.SiteEventId = Guid.NewGuid();
            evt.IsPublic = isPublic;
            evt.EventName = eventName;
            evt.AppName = appName;
            evt.EventRaiserId = raiserUserId;
            evt.EventContext = new XElement("Context",
                new XAttribute("XsltFolderInMod", xsltFolderInMod),
                new XElement("Events", 
                    new XAttribute("EventName", eventName),
                    context
                    ));
            evt.GroupId = groupId;
            evt.EventDate = DateTime.Now;
            scDataContext.Instance.Sc_SiteEvents.InsertOnSubmit(evt);
        }

        private static void CombineEventsInSameDay(out Sc_SiteEvent evt, ref XElement context, string appName, string eventName, Guid raiserUserId, Guid? groupId)
        {
            Sc_SiteEvent ev = GetSietEventInSameDay(appName, eventName, raiserUserId, groupId);
            evt = scDataContext.Instance.Sc_SiteEvents.Single(d => d.SiteEventId == ev.SiteEventId);
            XElement tmp = ev.EventContext;
            tmp.XPathSelectElement("Events").AddFirst(context);
            evt.EventContext = new XElement(tmp);
            evt.EventDate = DateTime.Now;
        }

        public static Sc_SiteEvent GetSietEventInSameDay(string appName, string eventName, Guid userId, Guid? groupId)
        {
            var q = GetEvents(userId, appName, eventName, true, 0, groupId, null, 0);

            return q.First();
        }

        public static List<Sc_SiteEvent> GetEvents(Guid? raiserUserName, string appName, string eventName, bool publicOnly, int daySpan, Guid? groupId, Guid? currnetUserId, int limitCount)
        {
            using (scDataContext cxt = new scDataContext())
            {
                //var q = scDataContext.Instance.GetSiteEvents(null, appName, eventName, daySpan, publicOnly);
                string query = string.Format("EXEC GetSiteEvents {0}, '{1}', '{2}', {3}, {4}, {5}, {6}, {7}", raiserUserName.HasValue ? "'" + raiserUserName.Value.ToString() + "'" : "NULL", appName, eventName,
                    daySpan, publicOnly, groupId.HasValue ? "'" + groupId.Value.ToString() + "'" : "NULL", currnetUserId.HasValue ? "'" + currnetUserId.Value.ToString() + "'" : "NULL", limitCount);
                //HttpContext.Current.Response.Write(query);
                var q = cxt.ExecuteQuery<Sc_SiteEvent>(query);

                return q.ToList();
                //return new List<Sc_SiteEvent>();
            }
        }

        public static string TransformTemplate(ref Sc_SiteEvent msg, Page pp)
        {
            if (page == null) page = pp;
            ClassLibrary.StringHelper h = new ClassLibrary.StringHelper(msg.EventContext.ToString());
            XElement trans = XElement.Parse(ContextConversion.GetTransformedXml(h.AsMemoryStream, msg.AppName, "EventContextTransform.xslt", msg.EventName, msg.EventRaiserId, Utility.FriendlyDateTime(msg.EventDate, TimeDisplayEnum.LiteralHoursNoTimeInOtherDays, false)));
            XElement contentToRender = trans.Element("Content");
            ContextConversion.TransformControls(ref contentToRender, page);

            return ClassLibrary.LinqToXmlHelper.GetInnerXml(contentToRender);
        }
    }
}
